#include<iostream>
#include"RingQueue.hpp"
#include<pthread.h>
#include<unistd.h>
#include"Task.hpp"
using namespace std;

#define Type Task 

int num = 1000;

void* productor(void* args)
{
    RingQueue<Type>* rq = static_cast<RingQueue<Type>*>(args);
    while(1)
    {
        cout<<num;
        int data1=rand()%10+1; //[1,10]
        
        //data1和data2因为执行太快，产生的值可能一样
        usleep(rand()%123);

        int data2=rand()%10+1; //[1,10]
        usleep(rand()%123);
        char oper = opers[rand()%opers.size()];

        Task t(data1,data2,oper);

        rq->Push(t);

        string task_string = t.PrintTask();
        cout<<"productor task: "<<task_string<<endl;
    }
}

void *consumer(void* args)
{
    RingQueue<Type>* rq = static_cast<RingQueue<Type>*>(args);
    while(1)
    {
        //sleep(1);

        Task t;
        rq->Pop(&t);
        t();

        string task_string = t.PrintResult();
        cout<<"consumer result: "<<task_string<<endl;
    }
}

int main()
{
    RingQueue<Type> *queue = new RingQueue<Type>();

    pthread_t pro1;
    pthread_t pro2;
    pthread_t pro3;
    pthread_t pro4;

    pthread_t con1;
    pthread_t con2;
    pthread_t con3;

    pthread_create(&pro1,nullptr,productor,(void*)queue);
    pthread_create(&pro2,nullptr,productor,(void*)queue);
    pthread_create(&pro3,nullptr,productor,(void*)queue);
    pthread_create(&pro4,nullptr,productor,(void*)queue);

    pthread_create(&con1,nullptr,consumer,(void*)queue);
    //pthread_create(&con2,nullptr,consumer,(void*)queue);
    //pthread_create(&con3,nullptr,consumer,(void*)queue);


    pthread_join(pro1,nullptr);
    pthread_join(pro2,nullptr);
    pthread_join(pro3,nullptr);
    pthread_join(pro4,nullptr);

    pthread_join(con1,nullptr);
    pthread_join(con2,nullptr);
    pthread_join(con3,nullptr);
}